C++ object definitions can be quite complex. In principle, your source code will need two kinds of things for each object that you use across more than one source file. First, you need an interface specification, describing its structure with type declarations and function prototypes. Second, you need the implementation itself. It can be tedious to maintain a separate interface description in a header file, in parallel to the actual implementation. It is also dangerous, since separate interface and implementation definitions may not remain parallel.
With GNU C++, you can use a single header file for both purposes.
Warning: The mechanism to specify this is in transition. For the nonce, you must use one of two#pragma
commands; in a future release of GNU C++, an alternative mechanism will make these#pragma
commands unnecessary.
The header file contains the full definitions, but is marked with
`#pragma interface
' in the source code. This allows the compiler
to use the header file only as an interface specification when ordinary
source files incorporate it with #include
. In the single source
file where the full implementation belongs, you can use either a naming
convention or `#pragma implementation
' to indicate this alternate
use of the header file.
#pragma interface
#pragma interface
' is included in a
compilation, this auxiliary information will not be generated (unless
the main input source file itself uses `#pragma implementation
').
Instead, the object files will contain references to be resolved at link
time.
#pragma implementation
#pragma implementation "objects.h"
#pragma interface
'.
Backup copies of inline member functions, debugging information, and the
internal tables used to implement virtual functions are all generated in
implementation files.
`#pragma implementation
' is implied whenever the
basename[1] of your source file matches the basename of a
header file it includes. There is no way to turn this off (other than
using a different name for one of the two files). In the same vein, if
you use `#pragma implementation
' with no argument, it applies to an
include file with the same basename as your source file. For example, in
`allclass.cc
', `#pragma implementation
' by itself is
equivalent to `#pragma implementation "allclass.h"
'; but even if
you do not say `#pragma implementation
' at all, `allclass.h
'
is treated as an implementation file whenever you include it from
`allclass.cc
'.
If you use an explicit `#pragma implementation
', it must appear in
your source file before you include the affected header files.
Use the string argument if you want a single implementation file to
include code from multiple header files. (You must also use
`#include
' to include the header file; `#pragma implementation
' only specifies how to use the file---it doesn't actually
include it.)
There is no way to split up the contents of a single header file into multiple implementation files.
`#pragma implementation
' and `#pragma interface
' also have an
effect on function inlining.
If you define a class in a header file marked with `#pragma interface
', the effect on a function defined in that class is similar to
an explicit extern
declaration---the compiler emits no code at
all to define an independent version of the function. Its definition
is used only for inlining with its callers.
Conversely, when you include the same header file in a main source file
that declares it as `#pragma implementation
', the compiler emits
code for the function itself; this defines a version of the function
that can be found via pointers (or by callers compiled without
inlining).
[1] A file's basename is the name stripped of all leading path information and of trailing suffixes, such as `.h
' or `.C
' or `.cc
'.